<?php

namespace app\libs;

use Closure;

use think\facade\Db;
use think\Exception;

class Auth
{

    private $app;

    protected $userResolver;

    protected $customCreators = [];

    protected $guards;


    public function __construct($app = null)
    {
        $this->app = $app;

        $this->userResolver = function ($guard = null) {
            return $this->guard($guard)->user();
        };
    }

    // Auth::guard(); 就是调用了这个方法
    public function guard($name = null)
    {
        // 首先查找$name, 没有就使用默认的驱动
        $name = $name ?: $this->getDefaultDriver();
        // 意思就是要实例化出这个驱动并且返回
        return isset($this->guards[$name])
            ? $this->guards[$name]
            : $this->guards[$name] = $this->resolve($name);
    }

    // 这里是构造Auth-guard驱动
    protected function resolve($name)
    {
        $config = $this->getConfig($name);
        if (is_null($config)) {
            throw new Exception("Auth guard [{$name}] is not defined.");
        }
        // 这里是如果你自己实现的驱动就返回
        if (isset($this->customCreators[$config['driver']])) {
            return $this->callCustomCreator($name, $config);
        }
        // 这里是系统默认两个类分别是
        // session 和 token 这里主要讲 sessionGuard
        $driverMethod = 'create' . ucfirst($config['driver']) . 'Driver';

        if (method_exists($this, $driverMethod)) {
            return $this->{$driverMethod}($name, $config);
        }

        throw new Exception("Auth guard driver [{$name}] is not defined.");
    }

    /**
     * Call a custom driver creator.
     *
     * @param  string $name
     * @param  array $config
     * @return mixed
     */
    protected function callCustomCreator($name, array $config)
    {
        return $this->customCreators[$config['driver']]($this->app, $name, $config);
    }

    /**
     * Create a session based authentication guard.
     *
     * @param string $name
     * @param array $config
     * @return mixed
     */
    public function createSessionDriver($name, $config = [])
    {
        $cookie = cookie($name);
        if ($cookie) {
            if (!session($name)) {
                session($name, json_decode($cookie, true));
            }
        }
        $guard = session($name);

        return $guard;
    }

    /**
     * Get the guard configuration.
     *
     * @param  string $name
     * @return array
     */
    protected function getConfig($name)
    {
        return config("auth.guards.{$name}");
    }

    // 默认的驱动是从配置文件里面读取的 /config/auth.php　default配置项
    public function getDefaultDriver()
    {
        return config('auth.defaults.guard');
    }

    /**
     * Dynamically call the default driver instance.
     *
     * @param  string $method
     * @param  array $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->guard()->{$method}(...$parameters);
    }

    /*public static function __callStatic($method, $parameters)
    {
        return (new static)->$method(...$parameters);
    }*/

}
